<?php

namespace Modules\Task\Providers;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\ServiceProvider;
use Modules\Openshop\Api\Douyin\Kernel\Exceptions\Exception;
use Modules\Task\Events\Executed;
use Modules\Task\Events\Executing;
use Modules\Task\Repositories\EloquentTaskRepository;
use Stancl\Tenancy\Tenancy;

class ConsoleServiceProvider extends ServiceProvider
{
    /**
     * Register any services.
     *
     * @return void
     */
    public function boot()
    {
        $cache_key = 'task_table_exist';
        $cache_exist = Cache::get($cache_key);
        if($cache_exist || Schema::hasTable("task_tasks")) {
            if(!$cache_exist){
                Cache::put($cache_key, 1);
            }
            $this->app->resolving(Schedule::class, function ($schedule) {
                $this->schedule($schedule);
            });
        };
    }

    /**
     * Prepare schedule from tasks.
     *
     * @param Schedule $schedule
     */
    public function schedule(Schedule $schedule)
    {
        $tasks = (new EloquentTaskRepository())->findAllActive();
        $tasks->each(function ($task) use ($schedule) {
            $event = $schedule->command($task->command, $task->compileParameters(true));
            // 初始化tenant环境
            try{
                Tenancy()->initialize($task->tenant_id);
                $event->cron($task->getCronExpression())
                    ->name($task->description)
                    ->timezone($task->timezone)
                    ->before(function () use ($task, $event) {
                        $event->start = microtime(true);
                        Executing::dispatch($task);
                    })
                    ->after(function () use ($event, $task) {
                        Log::debug('bef: '.storage_path($task->getMutexName()));
                        Executed::dispatch($task, $event->start ?? microtime(true));
                    })
                    ->sendOutputTo(storage_path($task->getMutexName()));
                if ($task->dont_overlap) {
                    $event->withoutOverlapping();
                }
                if ($task->run_in_maintenance) {
                    $event->evenInMaintenanceMode();
                }
                if ($task->run_on_one_server && in_array(config('cache.default'), ['memcached', 'redis', 'database', 'dynamodb'])) {
                    $event->onOneServer();
                }
                if ($task->run_in_background) {
                    $event->runInBackground();
                }
            }catch (\Exception $e) {
                return;
            }
        });
    }
}
